#Create a simulator object
set ns [new Simulator]
set f [open out.tr w]
$ns trace-all $f


#Define a 'finish' procedure
proc finish {} {

        global ns
        $ns flush-trace
        exit 0
}

proc connect {nodeA nodeB} {

    global ns
    $ns duplex-link $nodeA $nodeB 5Mb 2ms DropTail    
}

proc add_ftp {sender dest} {

    global ns

    set tcp_sender [new Agent/TCP]
    set tcp_dest [new Agent/TCPSink]
    
    $ns attach-agent $sender $tcp_sender
    $ns attach-agent $dest $tcp_dest
    $ns connect $tcp_sender $tcp_dest

    set ftp_sender [new Application/FTP]
    set ftp_dest [new Application/FTP]

    $ftp_sender attach-agent $tcp_sender

    return $ftp_sender
}


#rate is in Mb/s
# M = 1024*1024
# b = 1B / 8
proc add_cbr { src dest rate } {

    global ns

    set pktSize 500

    set udp [new Agent/UDP]
    $ns attach-agent $src $udp

    set cbr [new Application/Traffic/CBR]
    $cbr set packetSize_ $pktSize
    # calculate send interval to get desired rate
    $cbr set interval_ [ expr $pktSize / ($rate * 1024.0 * 1024 / 8) ]

    $cbr attach-agent $udp

    set null [new Agent/Null]
    $ns attach-agent $dest $null

    $ns connect $udp $null

    return $cbr
}

#Add logic here

#Create 4 nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]

#Connect then
connect $n0 $n2
connect $n1 $n2
connect $n2 $n3

#add ftp
set ftp [add_ftp $n0 $n3]

#add cbr
set cbr03 [add_cbr $n0 $n3 3]
set cbr13 [add_cbr $n1 $n3 4]

#send and stop
$ns at 0.5 "$ftp start"
$ns at 3   "$cbr03 start"
$ns at 4   "$cbr13 start"
$ns at 7   "$cbr13 stop"
$ns at 8   "$cbr03 stop"
$ns at 9   "$ftp stop"

#Define end time
$ns at 10.0 "finish"

#Run the simulation
$ns run

# ***Explicacao do que está acontecendo***

# A topologia da rede é como segue:

#   N0
#    =
#     =
#      N2===N3
#     =
#    =
#   N1

# Devido às novas fontes UDP adicionadas à simulação,
# nos nós N0 e N1, com fluxo destinado à N3, temos a
# sobrecarga do link (2,3) que é o gargalo da topologia.
# Com isso constata-se que o nó 2 passa a descartar
# pacotes, uma vez que sua fila enche.

# No arquivo de trace do ns, o descarte de pacotes
# é representado pela abreviação inicial 'd'. A seguir
# foi copiado um exemplo do trace de execução desta simu-
# lação.

# d 6.986847 2 3 cbr 500 ------- 0 1.0 3.2 3129 9822
# d 6.989159 2 3 cbr 500 ------- 0 0.1 3.1 3135 9826
# d 6.990662 2 3 cbr 500 ------- 0 1.0 3.2 3133 9829
# d 6.991702 2 3 cbr 500 ------- 0 0.1 3.1 3137 9831
# d 6.994245 2 3 cbr 500 ------- 0 0.1 3.1 3139 9835
# d 6.995516 2 3 cbr 500 ------- 0 0.1 3.1 3140 9838
# d 6.997337 2 3 cbr 500 ------- 0 1.0 3.2 3140 9841
# d 6.999331 2 3 cbr 500 ------- 0 0.1 3.1 3143 9845
# d 7.000603 2 3 cbr 500 ------- 0 0.1 3.1 3144 9847
# d 7.002106 2 3 cbr 500 ------- 0 1.0 3.2 3145 9850
# d 7.822352 0 2 tcp 1040 ------- 0 0.0 3.0 1907 10755
# d 7.82968 0 2 tcp 1040 ------- 0 0.0 3.0 1909 10765
# d 7.837872 0 2 tcp 1040 ------- 0 0.0 3.0 1913 10777
# d 7.838308 0 2 cbr 500 ------- 0 0.1 3.1 3805 10778

# Vemos que tanto os pacotes tcp quanto cbr são descartados
# pelo nó 2.